package luzhin;

import java.util.LinkedList;
import java.io.*;

/**
 * Implementation of class validating moves.
 * @author lacungus
 *
 */
public class AdvancedMoveValidator implements MoveValidator, Serializable {
	private static final long serialVersionUID = 235612573L;
	private SimpleMoveGenerator moveGenerator;
	private AttackDiagramBuilder diagramBuilder;
	
	/**
	 * Default constructor
	 */
	public AdvancedMoveValidator() {
		moveGenerator = new SimpleMoveGenerator();
		diagramBuilder = new AdvancedAttackDiagramBuilder();
	}

	// check to the one who moved
	private boolean checkMove(Board nb, AttackDiagram diagram) {
		boolean res = false;
		int kingPos = 0;
		for (int i=0;i<Board.SIZE;++i)
			if (!nb.isWhiteToMove() && nb.getPiece(i) == Piece.WK || nb.isWhiteToMove() && nb.getPiece(i) == Piece.BK)
				kingPos = i;
		if (!nb.isWhiteToMove() && diagram.getBlackAttacks()[kingPos] > 0 || nb.isWhiteToMove() && diagram.getWhiteAttacks()[kingPos] > 0)
			res = true;
		return res;
	}
	
	// check to the one who moved
	private boolean checkMove(Board board, Move move) {
		Board nb = new Board(board);
		nb.applyMove(move);
		AttackDiagram diagram = diagramBuilder.buildAttackDiagram(nb);
		return checkMove(nb, diagram);
	}
	
	/**
	 * @return true if the move is valid.  
	 */
	public boolean isValid(Board board, Move move) {
		LinkedList<Move> moves = moveGenerator.generateMoves(board);
		boolean ok = false;
		for (Move m : moves)
			ok = ok || m.equals(move);
		if (ok && checkMove(board, move))
			ok = false;
		return ok;
	}
}
